! ==============================================================================
! This file is part of CUPP (Community Unified Physics Package) since 2023.
! ==============================================================================

module atm_types_mod

  use cupp_mesh_mod
  use atm_const_mod
  use tracer_types_mod

  implicit none

  private

  public atm_state_type
  public atm_tend_type

  type atm_state_type
    integer :: id   = 0
    type(cupp_mesh_type), pointer :: mesh => null()
    real(r8), allocatable, dimension(:    ) :: lon      ! Cell center longitude (deg)
    real(r8), allocatable, dimension(:    ) :: lat      ! Cell center latitude (deg)
    real(r8), allocatable, dimension(:    ) :: area     ! Cell area (m2)
    ! Wind
    real(r8), allocatable, dimension(:,:  ) :: u        ! U-wind speed (m s-1)
    real(r8), allocatable, dimension(:,:  ) :: u_new    ! Updated u-wind speed (m s-1)
    real(r8), allocatable, dimension(:,:  ) :: v        ! V-wind speed (m s-1)
    real(r8), allocatable, dimension(:,:  ) :: v_new    ! Updated v-wind speed (m s-1)
    real(r8), allocatable, dimension(:    ) :: wsb      ! Wind speed on lowest model level (m s-1)
    real(r8), allocatable, dimension(:    ) :: u10      ! U-wind speed at 10m (m s-1)
    real(r8), allocatable, dimension(:    ) :: v10      ! V-wind speed at 10m (m s-1)
    ! Temperature
    real(r8), allocatable, dimension(:,:  ) :: t        ! Temperature (K)
    real(r8), pointer    , dimension(:    ) :: t_bot    ! Temperature at bottom of model (K)
    real(r8), allocatable, dimension(:,:  ) :: t_new    ! Temperature (K)
    real(r8), allocatable, dimension(:,:  ) :: tv       ! Virtual temperature (K)
    real(r8), allocatable, dimension(:,:  ) :: pt       ! Potential temperature (K)
    real(r8), allocatable, dimension(:,:  ) :: ptv      ! Virtual potential temperature (K)
    ! Pressure
    real(r8), allocatable, dimension(:,:  ) :: p        ! Full pressure (hydrostatic) on full levels (Pa)
    real(r8), allocatable, dimension(:,:  ) :: p_lev    ! Full pressure (hydrostatic) on half levels (Pa)
    real(r8), allocatable, dimension(:,:  ) :: pk       ! Exner function of full pressure (hydrostatic) on full levels
    real(r8), allocatable, dimension(:,:  ) :: pk_lev   ! Exner function of full pressure (hydrostatic) on half levels
    real(r8), allocatable, dimension(:,:  ) :: dp       ! Full pressure thickness (Pa)
    real(r8), allocatable, dimension(:,:  ) :: rdp      ! 1 / dp
    real(r8), allocatable, dimension(:,:  ) :: lnp_lev  ! Logrithm of full pressure on half levels
    real(r8), allocatable, dimension(:,:  ) :: omg      ! Vertical pressure velocity (Pa s-1)
    ! Height
    real(r8), allocatable, dimension(:,:  ) :: z        ! Height on full levels (m)
    real(r8), allocatable, dimension(:,:  ) :: z_lev    ! Height on half levels (m)
    real(r8), pointer    , dimension(:    ) :: zs       ! Terrain height (m)
    real(r8), allocatable, dimension(:,:  ) :: dz       ! Height thickness on full levels (m)
    ! Tracers
    ! NOTE: Dynamical core uses dry mixing ratios, but physics uses moist mixing ratios.
    real(r8), allocatable, dimension(:,:,:) :: q        ! Tracer mixing ratio (moist)
    ! Moisture
    real(r8), pointer    , dimension(:,:  ) :: qv       ! Water vapor mixing ratio (moist)
    real(r8), allocatable, dimension(:,:  ) :: qv_new   ! Water vapor mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qc       ! Cloud water mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qi       ! Cloud ice mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qr       ! Rain mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qs       ! Snow mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qg       ! Grauple mixing ratio (moist)
    real(r8), pointer    , dimension(:,:  ) :: qh       ! Hail mixing ratio (moist)
    ! Ozone
    real(r8), pointer    , dimension(:,:  ) :: qo3      ! Ozone mixing ratio (moist)
    ! Stability
    real(r8), allocatable, dimension(:,:  ) :: n2_lev   ! Square of Brunt-Väisälä frequency (s-2) on half levels
    real(r8), allocatable, dimension(:,:  ) :: ri_lev   ! Local Richardson number on half levels
    ! Surface layer
    real(r8), allocatable, dimension(:    ) :: emis     ! Surface emissivity
    real(r8), allocatable, dimension(:    ) :: alb      ! Surface albedo
    real(r8), allocatable, dimension(:    ) :: ps       ! Surface pressure (Pa)
    real(r8), allocatable, dimension(:    ) :: ts       ! Surface temperature (K)
    real(r8), allocatable, dimension(:    ) :: land     ! Land mask (1 for land, 2 for water)
    real(r8), allocatable, dimension(:    ) :: hfx      ! Upward heat flux at surface (W m-2)
    real(r8), allocatable, dimension(:    ) :: qfx      ! Upward moisture flux at surface (kg s-1 m-2)
    real(r8), allocatable, dimension(:    ) :: z0       ! Roughness height
    real(r8), allocatable, dimension(:    ) :: ustar    ! u* in similarity theory (m s-1)
    real(r8), allocatable, dimension(:    ) :: ptstar   ! pt* (K)
    real(r8), allocatable, dimension(:    ) :: psim     ! Similarity stability function for momentum
    real(r8), allocatable, dimension(:    ) :: psih     ! Similarity stability function for heat
    real(r8), allocatable, dimension(:    ) :: rib      ! Bulk Richardson number in surface layer
    real(r8), allocatable, dimension(:    ) :: uos      ! Sea surface zonal current (m s-1)
    real(r8), allocatable, dimension(:    ) :: vos      ! Sea surface meridional current (m s-1)
    real(r8), allocatable, dimension(:    ) :: t_2m     ! Temperature at 2m height (K)
    real(r8), allocatable, dimension(:    ) :: t_sfc    ! Surface or ground temperature (K)
    real(r8), allocatable, dimension(:    ) :: qv_2m    ! Water vapor mixing ratio? at 2m height (kg kg-1)
    ! Boundary layer
    real(r8), allocatable, dimension(:    ) :: pblh     ! PBL height (m)
    integer , allocatable, dimension(:    ) :: pblk     ! PBL level index
    real(r8), allocatable, dimension(:    ) :: wstar    ! Mixed-layer velocity scale (m s-1)
    real(r8), allocatable, dimension(:,:  ) :: exch_h   ! Exchange coefficient for heat (K m s-1)
    real(r8), allocatable, dimension(:,:  ) :: delta    ! Entrainment layer depth (m)
    ! Cloud
    real(r8), allocatable, dimension(:,:  ) :: cld      ! Total cloud fraction
    real(r8), allocatable, dimension(:,:  ) :: cld_cu   ! Cumulus cloud fraction
    real(r8), allocatable, dimension(:,:  ) :: cld_st   ! Stratiform cloud fraction
    ! Precipitation
    real(r8), allocatable, dimension(:    ) :: precl    ! Large scale precipitation
    ! Radiation
    real(r8), allocatable, dimension(:    ) :: swupt
    real(r8), allocatable, dimension(:    ) :: swuptc
    real(r8), allocatable, dimension(:    ) :: swdnt
    real(r8), allocatable, dimension(:    ) :: swdntc
    real(r8), allocatable, dimension(:    ) :: lwupt
    real(r8), allocatable, dimension(:    ) :: lwuptc
    real(r8), allocatable, dimension(:    ) :: lwdnt
    real(r8), allocatable, dimension(:    ) :: lwdntc
    real(r8), allocatable, dimension(:    ) :: swupb
    real(r8), allocatable, dimension(:    ) :: swupbc
    real(r8), allocatable, dimension(:    ) :: swdnb
    real(r8), allocatable, dimension(:    ) :: swdnbc
    real(r8), allocatable, dimension(:    ) :: lwupb
    real(r8), allocatable, dimension(:    ) :: lwupbc
    real(r8), allocatable, dimension(:    ) :: lwdnb
    real(r8), allocatable, dimension(:    ) :: lwdnbc
    real(r8), allocatable, dimension(:    ) :: swcf
    real(r8), allocatable, dimension(:    ) :: lwcf
    real(r8), allocatable, dimension(:    ) :: olr
    real(r8), allocatable, dimension(:    ) :: coszr
    ! Others
    real(r8), allocatable, dimension(:,:  ) :: rho      ! Full air density
    real(r8), pointer    , dimension(:    ) :: rho_bot  ! Full air density at bottom of model
    real(r8), allocatable, dimension(:,:  ) :: rhod     ! Dry air density
    real(r8), allocatable, dimension(:,:  ) :: cp       ! Specific heat capacity of total air in constant pressure
    real(r8), allocatable, dimension(:,:  ) :: cv       ! Specific heat capacity of total air in constant volume
    real(r8), allocatable, dimension(:,:  ) :: tep      ! Total enery in cp * T + gz + K
    real(r8), allocatable, dimension(:,:  ) :: tev      ! Total enery in cv * T + gz + K
  contains
    procedure :: init => atm_state_init
    procedure :: clear => atm_state_clear
    final :: atm_state_final
  end type atm_state_type

  type atm_tend_type
    integer :: ncol = 0
    integer :: nlev = 0
    real(r8), allocatable, dimension(:,:  ) :: dudt
    real(r8), allocatable, dimension(:,:  ) :: dvdt
    real(r8), allocatable, dimension(:,:  ) :: dtdt
    real(r8), allocatable, dimension(:,:,:) :: dqdt
    real(r8), allocatable, dimension(:,:  ) :: dptdt
    real(r8), allocatable, dimension(:,:  ) :: dptdt_rad
    logical :: updated_u  = .false.
    logical :: updated_v  = .false.
    logical :: updated_t  = .false.
    logical :: updated_pt = .false.
    logical, allocatable :: updated_q(:)
  contains
    procedure :: init  => atm_tend_init
    procedure :: clear => atm_tend_clear
    procedure :: reset => atm_tend_reset
    final :: atm_tend_final
  end type atm_tend_type

contains

  subroutine atm_state_init(this, mesh)

    class(atm_state_type), intent(inout), target :: this
    type(cupp_mesh_type), intent(in), target :: mesh

    call this%clear()

    this%id   = mesh%id
    this%mesh => mesh
    ! Wind
    allocate(this%u         (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%v         (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%wsb       (mesh%ncol_with_halo            ))
    allocate(this%u10       (mesh%ncol_with_halo            ))
    allocate(this%v10       (mesh%ncol_with_halo            ))
    ! Temperature
    allocate(this%t         (mesh%ncol_with_halo,mesh%nlev  )); this%t_bot => this%t(:,mesh%nlev)
    allocate(this%tv        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%pt        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%ptv       (mesh%ncol_with_halo,mesh%nlev  ))
    ! Pressure
    allocate(this%p         (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%p_lev     (mesh%ncol_with_halo,mesh%nlev+1))
    allocate(this%pk        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%pk_lev    (mesh%ncol_with_halo,mesh%nlev+1))
    allocate(this%dp        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%rdp       (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%lnp_lev   (mesh%ncol_with_halo,mesh%nlev+1))
    allocate(this%omg       (mesh%ncol_with_halo,mesh%nlev  ))
    ! Height
    allocate(this%z         (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%z_lev     (mesh%ncol_with_halo,mesh%nlev+1)); this%zs => this%z_lev(:,mesh%nlev+1)
    allocate(this%dz        (mesh%ncol_with_halo,mesh%nlev  ))
    ! Tracers
  if (ntracers > 0) then
    allocate(this%q         (mesh%ncol_with_halo,mesh%nlev  ,ntracers))
  end if
    ! Moisture

    if (idx_qv /= 0) this%qv => this%q(:,:,idx_qv)
    allocate(this%qv_new    (mesh%ncol_with_halo,mesh%nlev  ))
    if (idx_qc /= 0) this%qc => this%q(:,:,idx_qc)
    if (idx_qi /= 0) this%qi => this%q(:,:,idx_qi)
    if (idx_qr /= 0) this%qr => this%q(:,:,idx_qr)
    if (idx_qs /= 0) this%qs => this%q(:,:,idx_qs)
    if (idx_qg /= 0) this%qg => this%q(:,:,idx_qg)
    if (idx_qh /= 0) this%qh => this%q(:,:,idx_qh)
    ! Ozone
    if (idx_qo3 /= 0) this%qo3 => this%q(:,:,idx_qo3)
    ! Stability
    allocate(this%n2_lev    (mesh%ncol_with_halo,mesh%nlev+1))
    allocate(this%ri_lev    (mesh%ncol_with_halo,mesh%nlev+1))
    ! Surface layer
    allocate(this%emis      (mesh%ncol_with_halo            ))
    allocate(this%alb       (mesh%ncol_with_halo            ))
    allocate(this%ps        (mesh%ncol_with_halo            ))
    allocate(this%ts        (mesh%ncol_with_halo            ))
    allocate(this%land      (mesh%ncol_with_halo            ))
    allocate(this%hfx       (mesh%ncol_with_halo            ))
    allocate(this%qfx       (mesh%ncol_with_halo            ))
    allocate(this%z0        (mesh%ncol_with_halo            ))
    allocate(this%ustar     (mesh%ncol_with_halo            ))
    allocate(this%ptstar    (mesh%ncol_with_halo            ))
    allocate(this%psim      (mesh%ncol_with_halo            ))
    allocate(this%psih      (mesh%ncol_with_halo            ))
    allocate(this%rib       (mesh%ncol_with_halo            ))
    allocate(this%uos       (mesh%ncol_with_halo            ))
    allocate(this%vos       (mesh%ncol_with_halo            ))
    allocate(this%t_2m      (mesh%ncol_with_halo            ))
    allocate(this%t_sfc     (mesh%ncol_with_halo            ))
    allocate(this%qv_2m     (mesh%ncol_with_halo            ))
    ! Boundary layer
    allocate(this%pblh      (mesh%ncol_with_halo            ))
    allocate(this%pblk      (mesh%ncol_with_halo            ))
    allocate(this%wstar     (mesh%ncol_with_halo            ))
    allocate(this%exch_h    (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%delta     (mesh%ncol_with_halo,mesh%nlev  ))
    ! Cloud
    allocate(this%cld       (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%cld_cu    (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%cld_st    (mesh%ncol_with_halo,mesh%nlev  ))
    ! Precipitation
    allocate(this%precl     (mesh%ncol_with_halo            ))
    ! Radiation
    allocate(this%swupt     (mesh%ncol_with_halo            ))
    allocate(this%swuptc    (mesh%ncol_with_halo            ))
    allocate(this%swdnt     (mesh%ncol_with_halo            ))
    allocate(this%swdntc    (mesh%ncol_with_halo            ))
    allocate(this%lwupt     (mesh%ncol_with_halo            ))
    allocate(this%lwuptc    (mesh%ncol_with_halo            ))
    allocate(this%lwdnt     (mesh%ncol_with_halo            ))
    allocate(this%lwdntc    (mesh%ncol_with_halo            ))
    allocate(this%swupb     (mesh%ncol_with_halo            ))
    allocate(this%swupbc    (mesh%ncol_with_halo            ))
    allocate(this%swdnb     (mesh%ncol_with_halo            ))
    allocate(this%swdnbc    (mesh%ncol_with_halo            ))
    allocate(this%lwupb     (mesh%ncol_with_halo            ))
    allocate(this%lwupbc    (mesh%ncol_with_halo            ))
    allocate(this%lwdnb     (mesh%ncol_with_halo            ))
    allocate(this%lwdnbc    (mesh%ncol_with_halo            ))
    allocate(this%swcf      (mesh%ncol_with_halo            ))
    allocate(this%lwcf      (mesh%ncol_with_halo            ))
    allocate(this%olr       (mesh%ncol_with_halo            ))
    allocate(this%coszr     (mesh%ncol_with_halo            ))
    ! Others
    allocate(this%rho       (mesh%ncol_with_halo,mesh%nlev  )); this%rho_bot => this%rho(:,mesh%nlev)
    allocate(this%rhod      (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%cp        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%cv        (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%tep       (mesh%ncol_with_halo,mesh%nlev  ))
    allocate(this%tev       (mesh%ncol_with_halo,mesh%nlev  ))

  end subroutine atm_state_init

  subroutine atm_state_clear(this)

    class(atm_state_type), intent(inout) :: this

    ! Wind
    if (allocated(this%u        )) deallocate(this%u        )
    if (allocated(this%v        )) deallocate(this%v        )
    if (allocated(this%wsb      )) deallocate(this%wsb      )
    if (allocated(this%u10      )) deallocate(this%u10      )
    if (allocated(this%v10      )) deallocate(this%v10      )
    ! Temperature
    if (allocated(this%t        )) deallocate(this%t        )
    if (allocated(this%tv       )) deallocate(this%tv       )
    if (allocated(this%pt       )) deallocate(this%pt       )
    if (allocated(this%ptv      )) deallocate(this%ptv      )
    ! Pressure
    if (allocated(this%p        )) deallocate(this%p        )
    if (allocated(this%p_lev    )) deallocate(this%p_lev    )
    if (allocated(this%pk       )) deallocate(this%pk       )
    if (allocated(this%pk_lev   )) deallocate(this%pk_lev   )
    if (allocated(this%dp       )) deallocate(this%dp       )
    if (allocated(this%rdp      )) deallocate(this%rdp      )
    if (allocated(this%lnp_lev  )) deallocate(this%lnp_lev  )
    ! Height
    if (allocated(this%z        )) deallocate(this%z        )
    if (allocated(this%z_lev    )) deallocate(this%z_lev    )
    if (allocated(this%dz       )) deallocate(this%dz       )
    ! Tracers
    if (allocated(this%q        )) deallocate(this%q        )
    if (allocated(this%qv_new   )) deallocate(this%qv_new   )
    ! Stability
    if (allocated(this%n2_lev   )) deallocate(this%n2_lev   )
    if (allocated(this%ri_lev   )) deallocate(this%ri_lev   )
    ! Surface layer
    if (allocated(this%emis     )) deallocate(this%emis     )
    if (allocated(this%alb      )) deallocate(this%alb      )
    if (allocated(this%ps       )) deallocate(this%ps       )
    if (allocated(this%ts       )) deallocate(this%ts       )
    if (allocated(this%land     )) deallocate(this%land     )
    if (allocated(this%hfx      )) deallocate(this%hfx      )
    if (allocated(this%qfx      )) deallocate(this%qfx      )
    if (allocated(this%z0       )) deallocate(this%z0       )
    if (allocated(this%ustar    )) deallocate(this%ustar    )
    if (allocated(this%ptstar   )) deallocate(this%ptstar   )
    if (allocated(this%psim     )) deallocate(this%psim     )
    if (allocated(this%psih     )) deallocate(this%psih     )
    if (allocated(this%rib      )) deallocate(this%rib      )
    if (allocated(this%uos      )) deallocate(this%uos      )
    if (allocated(this%vos      )) deallocate(this%vos      )
    if (allocated(this%t_2m     )) deallocate(this%t_2m     )
    if (allocated(this%t_sfc    )) deallocate(this%t_sfc    )
    if (allocated(this%qv_2m    )) deallocate(this%qv_2m    )
    ! Boundary layer
    if (allocated(this%pblh     )) deallocate(this%pblh     )
    if (allocated(this%pblk     )) deallocate(this%pblk     )
    if (allocated(this%wstar    )) deallocate(this%wstar    )
    if (allocated(this%exch_h   )) deallocate(this%exch_h   )
    if (allocated(this%delta    )) deallocate(this%delta    )
    ! Precipitation
    if (allocated(this%precl    )) deallocate(this%precl    )
    ! Radiation
    if (allocated(this%swupt    )) deallocate(this%swupt    )
    if (allocated(this%swuptc   )) deallocate(this%swuptc   )
    if (allocated(this%swdnt    )) deallocate(this%swdnt    )
    if (allocated(this%swdntc   )) deallocate(this%swdntc   )
    if (allocated(this%lwupt    )) deallocate(this%lwupt    )
    if (allocated(this%lwuptc   )) deallocate(this%lwuptc   )
    if (allocated(this%lwdnt    )) deallocate(this%lwdnt    )
    if (allocated(this%lwdntc   )) deallocate(this%lwdntc   )
    if (allocated(this%swupb    )) deallocate(this%swupb    )
    if (allocated(this%swupbc   )) deallocate(this%swupbc   )
    if (allocated(this%swdnb    )) deallocate(this%swdnb    )
    if (allocated(this%swdnbc   )) deallocate(this%swdnbc   )
    if (allocated(this%lwupb    )) deallocate(this%lwupb    )
    if (allocated(this%lwupbc   )) deallocate(this%lwupbc   )
    if (allocated(this%lwdnb    )) deallocate(this%lwdnb    )
    if (allocated(this%lwdnbc   )) deallocate(this%lwdnbc   )
    if (allocated(this%swcf     )) deallocate(this%swcf     )
    if (allocated(this%lwcf     )) deallocate(this%lwcf     )
    if (allocated(this%olr      )) deallocate(this%olr      )
    if (allocated(this%coszr    )) deallocate(this%coszr    )
    ! Others
    if (allocated(this%rho      )) deallocate(this%rho      )
    if (allocated(this%rhod     )) deallocate(this%rhod     )
    if (allocated(this%cp       )) deallocate(this%cp       )
    if (allocated(this%cv       )) deallocate(this%cv       )
    if (allocated(this%tep      )) deallocate(this%tep      )
    if (allocated(this%tev      )) deallocate(this%tev      )

  end subroutine atm_state_clear

  subroutine atm_state_final(this)

    type(atm_state_type), intent(inout) :: this

    call this%clear()

  end subroutine atm_state_final

  subroutine atm_tend_init(this, ncol, nlev)

    class(atm_tend_type), intent(inout) :: this
    integer, intent(in) :: ncol
    integer, intent(in) :: nlev

    call this%clear()

    this%ncol = ncol
    this%nlev = nlev
    allocate(this%dudt      (this%ncol,this%nlev))
    allocate(this%dvdt      (this%ncol,this%nlev))
    allocate(this%dtdt      (this%ncol,this%nlev))
    allocate(this%dqdt      (this%ncol,this%nlev,ntracers))
    allocate(this%dptdt     (this%ncol,this%nlev))
    allocate(this%dptdt_rad (this%ncol,this%nlev)); this%dptdt_rad = 0
    allocate(this%updated_q (ntracers)); this%updated_q = .false.

  end subroutine atm_tend_init

  subroutine atm_tend_clear(this)

    class(atm_tend_type), intent(inout) :: this

    if (allocated(this%dudt     )) deallocate(this%dudt     )
    if (allocated(this%dvdt     )) deallocate(this%dvdt     )
    if (allocated(this%dtdt     )) deallocate(this%dtdt     )
    if (allocated(this%dqdt     )) deallocate(this%dqdt     )
    if (allocated(this%dptdt    )) deallocate(this%dptdt    )
    if (allocated(this%dptdt_rad)) deallocate(this%dptdt_rad)
    if (allocated(this%updated_q)) deallocate(this%updated_q)

  end subroutine atm_tend_clear

  subroutine atm_tend_final(this)

    type(atm_tend_type), intent(inout) :: this

    call this%clear()

  end subroutine atm_tend_final

  subroutine atm_tend_reset(this)

    class(atm_tend_type), intent(inout) :: this

    this%dudt  = 0; this%updated_u  = .false.
    this%dvdt  = 0; this%updated_v  = .false.
    this%dtdt  = 0; this%updated_t  = .false.
    this%dptdt = 0; this%updated_pt = .false.
    this%dqdt  = 0; this%updated_q  = .false.

  end subroutine atm_tend_reset

end module atm_types_mod
